﻿/* ===================================尊重原著======================================
 * 创 建 者：mao xiao jun 
 * 创建日期：2021-12-12
 * CLR Version : any
 * ===================================尊重原著=====================================*/
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Threading.Tasks;

namespace MTP
{
    public class MtpFactory
    {
        private static readonly Dictionary<string, IMtpClient> clients = new Dictionary<string, IMtpClient>();

        public static IMtpService CreateService(int port, string hostname, string cipher)
        {
            if (!IPAddress.TryParse(hostname, out IPAddress address))
            {
                address = Dns.GetHostEntry(hostname).AddressList.First(a => a.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork);
            }
            return new MtpService(port, address, cipher);
        }
        public static IMtpService CreateService(int port, IPAddress localaddr, string cipher)
        {
            return new MtpService(port, localaddr, cipher);
        }
        public static IMtpService CreateService(int port, string cipher)
        {
            return new MtpService(port, cipher);
        }


        public static IMtpClient GetClient(string hostname, int port, string cipher)
        {
            string key = $"{hostname}:{port}/{cipher}";
            lock (key)
            {

                if (clients.ContainsKey(key) && clients[key].IsConnected)
                {
                    return clients[key];
                }

                var client = GetClientAsync(hostname, port, cipher).GetAwaiter().GetResult();
                if (!clients.ContainsKey(key))
                {
                    clients.Add(key, client);
                    client.OnDisconnect(() =>
                    {
                        clients.Remove(key);
                    });
                }
                return client;
            }
        }


        private static async Task<IMtpClient> GetClientAsync(string hostname, int port, string cipher)
        {
            var client = new MtpClient(hostname, port, cipher);

            await client.ConnectAsync();

            return client;
        }
    }
}
